
local UP_DIR = 1;
local DOWN_DIR = 2;
local RIGHT_DIR = 6;
local LEFT_DIR = 3;
local DOWN_RUN = 4;
local LEFT_RUN = 5;
local RIGHT_RUN = 7;

function Entity:GetTable()
	
	local id = self.id;
	
	if( EntDataTable[id] == nil ) then
		return self:EngineGetTable();
	end
	
	return EntDataTable[id];
	
end

function Entity.Think()

	Entity.JumpThink();
	Entity.MoveThink();
	
end

local MovingEnts = { };
function Entity.MoveThink()
	
	for k, v in pairs( MovingEnts ) do
		
		if( not v:IsValid() ) then
			MovingEnts[k] = nil;
		else
		
		local xvel = 0;
		local yvel = 0;
		local p = v:GetPos();
		
		if( not v:GetTable().DestXReached ) then
			
			if( v:GetTable().LeftOfDest ) then
				
				if( p.x > v:GetTable().DestX ) then
					v:GetTable().DestXReached = true;
					p.x = v:GetTable().DestX;
					v:SetPos( v:GetTable().DestX, p.y );
				else
					xvel = v:GetTable().DestVel;
				
				end
				
			else
				
				if( p.x < v:GetTable().DestX ) then
					v:GetTable().DestXReached = true;
					p.x = v:GetTable().DestX;
					v:SetPos( v:GetTable().DestX, p.y );
				else
					xvel = v:GetTable().DestVel * -1;
					
				end
				
			end
			
		end
		
		
		if( not v:GetTable().DestYReached ) then
			
			if( v:GetTable().TopOfDest ) then
				
				if( p.y > v:GetTable().DestY ) then
					v:GetTable().DestYReached = true;
					p.y = v:GetTable().DestY;
					v:SetPos( p.x, v:GetTable().DestY );
				else
					yvel = v:GetTable().DestVel;
				end
				
			else
				
				if( p.y < v:GetTable().DestY ) then
					v:GetTable().DestYReached = true;
					p.y = v:GetTable().DestY;
					v:SetPos( p.x, v:GetTable().DestY );
				else
					yvel = v:GetTable().DestVel * -1;
				end
				
			end
			
		end
		
		v:SetConstantVelocity( xvel, yvel );
		
		if( xvel == 0 and yvel == 0 ) then
			
			v:IdleAnim();
			MovingEnts[k] = nil;
			
		end
		
		end
		
	end
	
end

function Entity:MoveTo( x, y, velocity, animate, alldirs )
	
	animate = animate or false;
	alldirs = alldirs or false;
	
	self:GetTable().DestAnimate = animate;
	self:GetTable().DestFullAnim = alldirs;
	self:GetTable().DestX = x;
	self:GetTable().DestY = y;
	self:GetTable().DestXReached = false;
	self:GetTable().DestYReached=  false;
	self:GetTable().MoveToDest = true;
	self:GetTable().DestVel = velocity;
	
	local p = self:GetPos();

	if( p.x > x ) then
		self:GetTable().LeftOfDest = false;
	elseif( p.x < x ) then
		self:GetTable().LeftOfDest = true;
	else
		self:GetTable().DestXReached = true;
	end
	
	if( p.y > y ) then
		self:GetTable().TopOfDest = false;
	elseif( p.y < y ) then
		self:GetTable().TopOfDest = true;
	else
		self:GetTable().DestYReached = true;
	end
	
	self:Face( x, y, alldirs );
	self:RunAnim();

	table.insert( MovingEnts, self );
	
end


function Entity:ProjectAt( x, y, speed )
	
	speed = speed or 200;
	
	local pos = self:GetPos();
	
	local dist = GetDistance( x, y, pos.x, pos.y );
	local xvel = ( x - pos.x ) / dist;
	local yvel = ( y - pos.x ) / dist;

	self:SetConstantVelocity( speed * xvel, speed * yvel );
	
end

local JumpingEnts = { };

function Entity:Jump( x, y )
	
	self:GetTable().OrigY = self:GetPos().y;
	self:GetTable().VelX = x;
	self:GetTable().VelY = y;
	
	self:SetConstantVelocity( x, y );
	
	table.insert( JumpingEnts, self );
	
end

function Entity.JumpThink()
	
	for k, v in pairs( JumpingEnts ) do
		
		if( not v:IsValid() ) then
			JumpingEnts[k] = nil;
		else
		
		v:GetTable().VelY = v:GetTable().VelY + 800 * GetDPS();
		
		v:SetConstantVelocity( v:GetTable().VelX, v:GetTable().VelY );
		
		local pos = v:GetPos();
		
		if( pos.y > v:GetTable().OrigY ) then
			
			v:SetPos( pos.x, pos.y );
			v:SetConstantVelocity( 0, 0 );
			JumpingEnts[k] = nil;
			
		end
		
		end
		
	end
	
end

function Entity:Face( x, y, multidir )
	
	local pos = self:GetPos();
	
	if( pos.x > x ) then
		
		if( not multidir or ( pos.x - x > 200 and math.abs( pos.y - y ) < 400 ) ) then
		
			if( multidir ) then
			
				self:SetCurrentSpriteBind( LEFT_DIR );
			
			end
		
		else
			
			if( pos.y > y ) then
				self:SetCurrentSpriteBind( UP_DIR );
			else
				self:SetCurrentSpriteBind( DOWN_DIR );
			end
			
		end
		
	else
		
		if( not multidir or ( pos.x - x < -200 and math.abs( pos.y - y ) < 400 ) ) then
		
			if( multidir ) then
		
				self:SetCurrentSpriteBind( RIGHT_DIR );
			
			end
		
		else
			
			if( pos.y > y ) then
				self:SetCurrentSpriteBind( UP_DIR );
			else
				self:SetCurrentSpriteBind( DOWN_DIR );
			end
			
		end
		
	end
	
end